import ast
from typing import List, Optional

from 程序核心代码.ast节点.节点定义.具体ast节点.操作类.简单语句模板 import 简单语句ast节点基础模型
from 程序核心代码.mvvm重构.基础定义.节点管理器.自动节点注册表 import 注册节点模型, 节点模型匹配器


@注册节点模型(ast.Break)
class 循环中断节点(简单语句ast节点基础模型):
    def __init__(self,ast节点, 所属节点模型管理器, 上级节点: Optional['ast节点基础模型'] = None, 节点位置: Optional[List] = None):

        self.获取属性("节点名称") = "循环中断"
        super().__init__(ast节点, 所属节点模型管理器, 上级节点=上级节点, 节点位置=节点位置 )
        self.节点介绍 = "中断当前循环 跳出当前容器"
        self.添加接口到节点("控制流", "输入", 必须连接=True)
        self.添加接口到节点("控制流", "输出", 必须连接=True)
        #控制输出应该跨出当前循环容器
@注册节点模型(ast.Continue)
class 循环跳过节点(简单语句ast节点基础模型):
    def __init__(self,ast节点, 所属节点模型管理器, 上级节点: Optional['ast节点基础模型'] = None, 节点位置: Optional[List] = None):

        self.获取属性("节点名称") = "循环跳过"
        super().__init__(ast节点, 所属节点模型管理器, 上级节点=上级节点, 节点位置=节点位置)
        self.节点介绍 = "跳过当前循环的剩余部分，回到循环开始的地方"
        self.添加接口到节点("控制流", "输入", 必须连接=True)
        self.添加接口到节点("控制流", "输出", 必须连接=True)
        # 控制输出应该连接到当前容器的起始操作类节点
@注册节点模型(ast.Pass)
class 占位节点(简单语句ast节点基础模型):
    def __init__(self,ast节点, 所属节点模型管理器, 上级节点: Optional['ast节点基础模型'] = None, 节点位置: Optional[List] = None):

        self.获取属性("节点名称") = "结构占位"
        super().__init__(ast节点, 所属节点模型管理器, 上级节点=上级节点, 节点位置=节点位置)
        self.节点介绍 = "无实际功能"
        self.是控制节点 = False
        # 占位节点 不需要任何接口
@注册节点模型(ast.Return)
class 结束节点(简单语句ast节点基础模型):
    def __init__(self,ast节点, 所属节点模型管理器, 上级节点: Optional['ast节点基础模型'] = None, 节点位置: Optional[List] = None):
        self.获取属性("节点名称") = "结束并抛出"
        super().__init__(ast节点, 所属节点模型管理器, 上级节点=上级节点, 节点位置=节点位置)
        self.节点介绍 = "结束当前函数，并返回指定的值"
        if hasattr(self._ast节点, 'value'):
            self.返回值 = 节点模型匹配器(self._ast节点.value, self.所属节点模型管理器)
            if self.返回值:
                起始接口 = self.返回值.添加接口到节点("调用流", "输出", 必须连接=False)
                结束接口=self.添加接口到节点("调用流", "输入", 必须连接=False)
                起始接口.接口创建连接线模型(结束接口, self)
        else:
            self.返回值 = None
        self.添加接口到节点("控制流", "输入", 必须连接=False)
        # 结束节点 不需要任何输出接口


@注册节点模型(ast.Delete)
class 删除节点(简单语句ast节点基础模型):
    def __init__(self,ast节点, 所属节点模型管理器, 上级节点: Optional['ast节点基础模型'] = None, 节点位置: Optional[List] = None):
        self.获取属性("节点名称") = "删除节点"
        super().__init__(ast节点, 所属节点模型管理器, 上级节点=上级节点, 节点位置=节点位置)
        self.节点介绍 = "删除传入的存储节点"
        for 目标 in self._ast节点.targets:
            目标节点= 节点模型匹配器(目标, self.所属节点模型管理器)
            起始接口 = 目标节点.添加接口到节点("调用流", "输出", 必须连接=False)
            结束接口 = self.添加接口到节点("调用流", "输入", 必须连接=False)
            起始接口.接口创建连接线模型(结束接口, self)

        self.添加接口到节点("控制流", "输入", 必须连接=False)

@注册节点模型(ast.Raise)
class 抛出异常节点(简单语句ast节点基础模型):
    def __init__(self,ast节点, 所属节点模型管理器, 上级节点: Optional['ast节点基础模型'] = None, 节点位置: Optional[List] = None):
        self.获取属性("节点名称") = "抛出异常节点"
        super().__init__(ast节点, 所属节点模型管理器, 上级节点=上级节点, 节点位置=节点位置)
        self.节点介绍 = "检测到异常并抛出"
        当前异常=节点模型匹配器(self._ast节点.exc, self.所属节点模型管理器)
        起始接口 = 当前异常.添加接口到节点("调用流", "输出", 必须连接=False)
        结束接口 = self.添加接口到节点("调用流", "输入","当前异常", 必须连接=False)
        起始接口.接口创建连接线模型(结束接口, self)
        #检查是否有cause属性
        if hasattr(self._ast节点, 'cause'):
            # print(type(起始接口._ast节点))
            # print(dir(起始接口._ast节点))
            if self._ast节点.cause:
                print(ast.dump(self._ast节点, annotate_fields=True, indent=4))
                原始异常=节点模型匹配器(self._ast节点.cause, self.所属节点模型管理器)
                起始接口 = 原始异常.添加接口到节点("调用流", "输出", 必须连接=False)
                结束接口 = self.添加接口到节点("调用流", "输入", "原始异常", 必须连接=False)
                起始接口.接口创建连接线模型(结束接口, self)

        self.添加接口到节点("控制流", "输入", 必须连接=False)
